package com.distributed.lock.utils;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @program: SpringBootDemos
 * @description:
 * @author: Kangsen
 * @create: 2022-07-13 16:07
 *
 *
 * lock.lock() 不设置锁过期时间 在线程拿到锁后，
 * 默认过期时间是30s，同时会启动看门狗的定时任务  每10s自动续期30s
 *
 *
 **/
@Component
public class RedissonUtils {

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 加锁
     * @param lockKey
     * @return
     */
    public RLock lock(String lockKey){
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock();
        return lock;
    }

    /**
     * 加锁
     * @param lockKey  锁key
     * @param timeout  锁超时时间 单位:s
     * @return
     */
    public RLock lock(String lockKey,Long timeout){
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout, TimeUnit.SECONDS);
        return lock;
    }

    /**
     * 加锁
     * @param lockKey  锁key
     * @param timeout   超时时间
     * @param timeUnit  超时时间单位
     * @return
     */
    public RLock lock(String lockKey,Long timeout,TimeUnit timeUnit){
        RLock lock = redissonClient.getLock(lockKey);
        lock.lock(timeout,timeUnit);
        return lock;
    }

    /**
     * 尝试获取锁
     * @param lockKey  锁 key
     * @param waitTime  最长等待时间
     * @param leaseTime 加锁后自动释放锁时间
     * @return
     */
    public RLock tryLockObj(String lockKey,int waitTime,int leaseTime){
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime,leaseTime,TimeUnit.SECONDS)?lock:null;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public boolean tryLock(String lockKey,int waitTime,int leaseTime){
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime,leaseTime,TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 尝试获取锁
     * @param lockKey 锁key
     * @param waitTime 未拿到锁的最长等待时间  知道有进程拿到锁后立即返回
     * @param leaseTime 加锁后释放锁时间
     * @param timeUnit 时间单位
     * @return
     */
    public boolean tryLock(String lockKey,int waitTime,int leaseTime,TimeUnit timeUnit){
        RLock lock = redissonClient.getLock(lockKey);
        try {
            return lock.tryLock(waitTime,leaseTime,timeUnit);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 释放锁
     * @param lockKey
     */
    public void unlock(String lockKey){
        RLock lock = redissonClient.getLock(lockKey);
        lock.unlock();
    }

    /**
     * 释放锁
     * @param lock
     */
    public void unlock(RLock lock){
        if(!Objects.isNull(lock)){
            lock.unlock();
        }
    }
}
